package com.gameShare.aspect

import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.gameShare.enums.misc.ResponseCodeEnum
import com.gameShare.exceptions.BusinessException
import com.gameShare.service.misc.CaptchaService
import com.gameShare.service.misc.RedisService
import com.gameShare.utils.StringUtils
import jakarta.servlet.http.HttpServletRequest
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component

@Aspect
@Component
open class CaptchaVerifyAspect(
        private val captchaService: CaptchaService,
        private val objectMapper: ObjectMapper,
        private val redisService: RedisService
    ) {

    private val logger = LoggerFactory.getLogger(CaptchaVerifyAspect::class.java)

    /**
     * 验证码的校验验证码校验放在header里面带来
     *  检查是否匹配然后删除验证码
     * @param joinPoint aop接入点
     */
    @Before("@annotation(com.gameShare.annotation.VerifyCaptcha)")
    fun verifyCaptcha(joinPoint: JoinPoint) {
        val request = joinPoint.args[0] as HttpServletRequest
        val captchaKey = request.getHeader("captcha-key")
            ?: throw BusinessException(ResponseCodeEnum.ARGUMENT_ERROR)
        StringUtils.checkPathIsOk(captchaKey)
        try {
            val captchaAnswer = objectMapper.readValue(
                request.getHeader("captcha-answer")
                    ?: throw BusinessException(ResponseCodeEnum.ARGUMENT_ERROR),
                object : TypeReference<List<Int>>() {}
            )
                ?: throw BusinessException(ResponseCodeEnum.ARGUMENT_ERROR)

            if(!captchaService.verifyCaptcha(captchaKey , captchaAnswer))
                throw BusinessException(ResponseCodeEnum.ARGUMENT_ERROR.code, "验证码输入错误")
            redisService.delCaptchaAnswer(captchaKey)
        } catch (e : JsonProcessingException) {
            logger.warn("读取验证码数据异常$captchaKey", e)
            throw BusinessException(ResponseCodeEnum.SERVER_ERROR)
        }


    }
}